﻿using System;
using System.Collections.Specialized;
using System.Web;
using ElectronicCommerce.Framework.Utility;
using ElectronicCommerce.Framework.Web.Configuration;
using ElectronicCommerce.Framework.Web.Configuration.Resource;
using ElectronicCommerce.Framework.Web.Configuration.Website;
using System.Text;

namespace ElectronicCommerce.Framework.Web.ResourceManagement
{
    public class UrlBuilder
    {
        private QueryStringBuilder m_QueryStringBuilder = new QueryStringBuilder();

        public UrlBuilder()
            : this(Encodings.UTF8)
        {
        }

        public UrlBuilder(Encoding contentEncoding)
        {
            this.ContentEncoding = contentEncoding;
        }

        /// <summary>
        /// 对参数值的编码
        /// </summary>
        public Encoding ContentEncoding { get; private set; }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public string BuildUrl(string url)
        {
            if (m_QueryStringBuilder.ParameterCount > 0)
            {
                return string.Format("{0}?{1}", url.ToLower(), m_QueryStringBuilder.ToString());
            }
            else
            {
                return url.ToLower();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="queryStrings"></param>
        /// <returns></returns>
        public string BuildUrl(string url, NameValueCollection queryStrings)
        {
            QueryStringBuilder queryStringBuilder = new QueryStringBuilder(queryStrings, ContentEncoding);
            return BuildUrl(url.ToLower(), queryStringBuilder);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="queryStringBuilder"></param>
        /// <returns></returns>
        public string BuildUrl(string url, QueryStringBuilder queryStringBuilder)
        {
            string baseUrl = url;
            if (url.StartsWith("~/"))
            {
                baseUrl = VirtualPathUtility.ToAbsolute(url);
            }
            if (queryStringBuilder != null && queryStringBuilder.ParameterCount > 0)
            {
                return string.Format("{0}?{1}", baseUrl.ToLower(), queryStringBuilder.ToString());
            }
            else
            {
                return baseUrl.ToLower();
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        public string BuildUrlWithCurrentQueryString(string url)
        {
            QueryStringBuilder queryStringBuilder = new QueryStringBuilder(HttpContext.Current.Request.QueryString, ContentEncoding);
            if (queryStringBuilder.ParameterCount > 0)
            {
                return string.Format("{0}?{1}", url.ToLower(), queryStringBuilder.ToString());
            }
            else
            {
                return url.ToLower();
            }
        }

        /// <summary>
        /// 构造带有服务器的Url地址
        /// </summary>
        /// <param name="pageAlias"></param>
        /// <returns></returns>
        public string BuildPageUrl(Enum pageAlias)
        {
            return BuildPageUrl(pageAlias, m_QueryStringBuilder);
        }

        /// <summary>
        /// 构造带有服务器的Url地址
        /// </summary>
        /// <param name="pageAlias"></param>
        /// <param name="queryStrings"></param>
        /// <returns></returns>
        public string BuildPageUrl(Enum pageAlias, NameValueCollection queryStrings)
        {
            QueryStringBuilder queryStringBuilder = new QueryStringBuilder(queryStrings, ContentEncoding);
            return BuildPageUrl(pageAlias, queryStringBuilder);
        }

        /// <summary>
        /// Builds the URL.
        /// </summary>
        /// <param name="pageAlias">The URL alias.</param>
        /// <param name="queryString">The query string. in the format of param1, value1, param2, value2, ...</param>
        /// <returns></returns>
        public string BuildPageUrl(Enum pageAlias, params string[] queryString)
        {
            QueryStringBuilder builder = new QueryStringBuilder(ContentEncoding);
            for (int i = 0; i < queryString.Length; i += 2)
            {
                if (i + 1 >= queryString.Length)
                {
                    break;
                }
                builder.AddQueryString(queryString[i].ToLower(), queryString[i + 1]);
            }

            return BuildPageUrl(pageAlias, builder);
        }

        /// <summary>
        /// 构造带有服务器的Url地址
        /// </summary>
        /// <param name="pageAlias"></param>
        /// <param name="queryStringBuilder"></param>
        /// <returns></returns>
        public string BuildPageUrl(Enum pageAlias, QueryStringBuilder queryStringBuilder)
        {
            PageInfo pageInfo = ConfigHelper.PageConfig.GetPageInfo(pageAlias.ToString());

            if (pageInfo == null)
            {
                //throw config not found excpetion
                throw new ArgumentException(string.Format("Page Alias: [{0}] was not found in Pages.config.", pageAlias));
            }

            return BuildPageUrl(pageInfo.Path.ToLower(), queryStringBuilder, pageInfo.HttpProtocol);
        }

        private string BuildPageUrl(string virtualPath, QueryStringBuilder queryStringBuilder, HttpProtocol protocol)
        {
            string host = string.Empty;
            SiteConfig config = ConfigHelper.WebsiteConfig;

            if (config == null)
            {
                throw new ArgumentException(string.Format("Website Config was not loadded correctly (website.config)."));
            }

            switch (protocol)
            {
                case HttpProtocol.Http:
                    host = config.HttpSite.TrimEnd('\\', '/');
                    break;

                case HttpProtocol.Https:
                    host = config.HttpsSite.TrimEnd('\\', '/');
                    break;

                case HttpProtocol.Nonspecific:
                    break;
            }

            string url = string.Format("{0}/{1}", host, VirtualPathUtility.ToAbsolute(virtualPath).TrimStart('\\', '/'));

            if (queryStringBuilder != null && queryStringBuilder.ParameterCount > 0)
            {
                return string.Format("{0}?{1}", url.ToLower(), queryStringBuilder.ToString());
            }
            else
            {
                return url.ToLower();
            }
        }

        #region Obsolete methods
        /// <summary>
        /// Adds parameter to the url
        /// </summary>
        /// <param name="name">name of the parameter, cannot be url-encoded.</param>
        /// <param name="val">value of the parameter, cannot be url-encoded.</param>
        [Obsolete]
        public void AddQueryParameter(string name, string val)
        {
            if (m_QueryStringBuilder == null)
            {
                m_QueryStringBuilder = new QueryStringBuilder(ContentEncoding);
            }
            if (!string.IsNullOrEmpty(name) &&
                !string.IsNullOrEmpty(val))
            {
                m_QueryStringBuilder.AddQueryString(name.ToLower(), val);
            }
        }
        /// <summary>
        /// 构造不带有服务器的Url地址
        /// </summary>
        /// <param name="pageAlias"></param>
        /// <returns></returns>
        [Obsolete]
        public string BuildUrl(Enum pageAlias)
        {
            return BuildUrl(pageAlias, m_QueryStringBuilder);
        }

        /// <summary>
        /// 构造不带有服务器的Url地址
        /// </summary>
        /// <param name="pageAlias"></param>
        /// <param name="queryStrings"></param>
        /// <returns></returns>
        [Obsolete]
        public string BuildUrl(Enum pageAlias, NameValueCollection queryStrings)
        {
            QueryStringBuilder queryStringBuilder = new QueryStringBuilder(queryStrings, ContentEncoding);
            return BuildUrl(pageAlias, queryStringBuilder);
        }

        /// <summary>
        /// 构造不带有服务器的Url地址
        /// 如：PageAlias对应的页面路径 ~/Customer/Edit.aspx， 则会生成/Customer/Edit.aspx
        /// </summary>
        /// <param name="pageAlias"></param>
        /// <param name="queryStringBuilder"></param>
        /// <returns></returns>
        [Obsolete]
        public string BuildUrl(Enum pageAlias, QueryStringBuilder queryStringBuilder)
        {
            return BuildPageUrl(pageAlias, queryStringBuilder);

            //PageInfo pageInfo = ConfigHelper.PageConfig.GetPageInfo(pageAlias.ToString());
            ////[junyu.chen] build url from PageInfo, HttpProtocol is required.
            //return BuildPageUrl(pageInfo.Path.ToLower(), queryStringBuilder, pageInfo.HttpProtocol);
        }
        /// <summary>
        /// 构造带有服务器的Url地址
        /// </summary>
        /// <param name="pageAlias"></param>
        /// <param name="queryStrings"></param>
        /// <returns></returns>
        [Obsolete]
        public string BuildPageUrl(Enum pageAlias, NameValueCollection queryStrings, bool isSecure)
        {
            return BuildPageUrl(pageAlias, queryStrings);
        }

        /// <summary>
        /// 构造带有服务器的Url地址
        /// </summary>
        /// <param name="pageAlias"></param>
        /// <returns></returns>
        [Obsolete]
        public string BuildPageUrl(Enum pageAlias, bool isSecure)
        {
            return BuildPageUrl(pageAlias, m_QueryStringBuilder);
        }

        /// <summary>
        /// 构造带有服务器的Url地址
        /// 如：PageAlias对应的页面路径 ~/Customer/Edit.aspx， 则会生成类似http://server/Customer/Edit.aspx
        /// </summary>
        /// <param name="pageAlias"></param>
        /// <param name="queryStringBuilder"></param>
        /// <returns></returns>
        [Obsolete]
        public string BuildPageUrl(Enum pageAlias, QueryStringBuilder queryStringBuilder, bool isSecure)
        {
            return BuildPageUrl(pageAlias, queryStringBuilder);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="virtualPath"></param>
        /// <param name="queryStringBuilder"></param>
        /// <returns></returns>
        [Obsolete]
        public string BuildPageUrl(string virtualPath, QueryStringBuilder queryStringBuilder, bool isSecure)
        {
            string baseUrl = string.Format("{0}/{1}",
                isSecure ? ConfigHelper.WebsiteConfig.HttpsSite.TrimEnd('\\', '/') : ConfigHelper.WebsiteConfig.HttpSite.TrimEnd('\\', '/'),
                VirtualPathUtility.ToAbsolute(virtualPath).TrimStart('\\', '/'));


            if (queryStringBuilder != null && queryStringBuilder.ParameterCount > 0)
            {
                return string.Format("{0}?{1}", baseUrl.ToLower(), queryStringBuilder.ToString());
            }
            else
            {
                return baseUrl.ToLower();
            }
        }
        #endregion
    }
}
